/*---------------------------------------------------------------------------------------------

 @author       Constantin Saguin - @brutaldesign
 @link            http://csag.co
 @github        http://github.com/brutaldesign/swipebox
 @version     1.2.1
 @license      MIT License

 ----------------------------------------------------------------------------------------------*/

;(function (window, document, $, undefined) {

    $.swipebox = function(elem, options) {

        var defaults = {
                useCSS : true,
                initialIndexOnArray : 0,
                hideBarsDelay : 0,
                videoMaxWidth : 1140,
                vimeoColor : 'CCCCCC',
                beforeOpen: null,
                afterClose: null
            },

            plugin = this,
            elements = [], // slides array [{href:'...', title:'...'}, ...],
            elem = elem,
            selector = elem.selector,
            $selector = $(selector),
            isTouch = document.createTouch !== undefined || ('ontouchstart' in window) || ('onmsgesturechange' in window) || navigator.msMaxTouchPoints,
            supportSVG = !!(window.SVGSVGElement),
            winWidth = window.innerWidth ? window.innerWidth : $(window).width(),
            winHeight = window.innerHeight ? window.innerHeight : $(window).height(),
            html = '<div id="swipebox-overlay">\
                <a id="swipebox-close"></a>\
				<div id="swipebox-backdrop"> </div>\
				<div id="swipebox-slider"></div>\
				<div id="swipebox-caption"></div>\
				<div id="swipebox-action">\
					<a id="swipebox-prev"></a>\
					<a id="swipebox-next"></a>\
				</div>\
		</div>';

        plugin.settings = {}

        plugin.init = function(){

            plugin.settings = $.extend({}, defaults, options);

            if ($.isArray(elem)) {

                elements = elem;
                ui.target = $(window);
                ui.init(plugin.settings.initialIndexOnArray);

            }else{

                $selector.click(function(e){
                    elements = [];
                    var index , relType, relVal;

                    if (!relVal) {
                        relType = 'rel';
                        relVal  = $(this).attr(relType);
                    }

                    if (relVal && relVal !== '' && relVal !== 'nofollow') {
                        $elem = $selector.filter('[' + relType + '="' + relVal + '"]');
                    }else{
                        $elem = $(selector);
                    }

                    $elem.each(function(){

                        var title = null, href = null;

                        if( $(this).attr('title') )
                            title = $(this).attr('title');

                        if( $(this).attr('href') )
                            href = $(this).attr('href');

                        elements.push({
                            href: href,
                            title: title
                        });
                    });

                    index = $elem.index($(this));
                    e.preventDefault();
                    e.stopPropagation();
                    ui.target = $(e.target);
                    ui.init(index);
                });
            }
        }

        plugin.refresh = function() {
            if (!$.isArray(elem)) {
                ui.destroy();
                $elem = $(selector);
                ui.actions();
            }
        }

        var ui = {

            init : function(index){
                if (plugin.settings.beforeOpen)
                    plugin.settings.beforeOpen();
                this.target.trigger('swipebox-start');
                $.swipebox.isOpen = true;
                this.build();
                this.openSlide(index);
                this.openMedia(index);
                this.preloadMedia(index+1);
                this.preloadMedia(index-1);
            },

            build : function(){
                var $this = this;

                $('body').append(html);

                if($this.doCssTrans()){
                    $('#swipebox-slider').css({
                        '-webkit-transition' : 'left 0.4s ease',
                        '-moz-transition' : 'left 0.4s ease',
                        '-o-transition' : 'left 0.4s ease',
                        '-khtml-transition' : 'left 0.4s ease',
                        'transition' : 'left 0.4s ease'
                    });
                    $('#swipebox-overlay').css({
                        '-webkit-transition' : 'opacity 1s ease',
                        '-moz-transition' : 'opacity 1s ease',
                        '-o-transition' : 'opacity 1s ease',
                        '-khtml-transition' : 'opacity 1s ease',
                        'transition' : 'opacity 1s ease'
                    });
                    $('#swipebox-action, #swipebox-caption').css({
                        '-webkit-transition' : '0.5s',
                        '-moz-transition' : '0.5s',
                        '-o-transition' : '0.5s',
                        '-khtml-transition' : '0.5s',
                        'transition' : '0.5s'
                    });
                }


//                if(supportSVG){
//                    var bg = $('#swipebox-close').css('background-image');
//                    bg = bg.replace('png', 'svg');
//                    $('#swipebox-action #swipebox-prev,#swipebox-action #swipebox-next,#swipebox-action #swipebox-close').css({
//                        'background-image' : bg
//                    });
//                }

                $.each( elements,  function(){
                    $('#swipebox-slider').append('<div class="slide"></div>');
                });

                $this.setDim();
                $this.actions();
                $this.keyboard();
                $this.gesture();
                $this.animBars();
                $this.resize();

            },

            setDim : function(){

                var width, height, sliderCss = {};

                if( "onorientationchange" in window ){

                    window.addEventListener("orientationchange", function() {
                        if( window.orientation == 0 ){
                            width = winWidth;
                            height = winHeight;
                        }else if( window.orientation == 90 || window.orientation == -90 ){
                            width = winHeight;
                            height = winWidth;
                        }
                    }, false);


                }else{

                    width = window.innerWidth ? window.innerWidth : $(window).width();
                    height = window.innerHeight ? window.innerHeight : $(window).height();
                }

                sliderCss = {
                    width : width,
                    height : height
                }


                $('#swipebox-overlay').css(sliderCss);

            },

            resize : function (){
                var $this = this;

                $(window).resize(function() {
                    $this.setDim();
                }).resize();
            },

            supportTransition : function() {
                var prefixes = 'transition WebkitTransition MozTransition OTransition msTransition KhtmlTransition'.split(' ');
                for(var i = 0; i < prefixes.length; i++) {
                    if(document.createElement('div').style[prefixes[i]] !== undefined) {
                        return prefixes[i];
                    }
                }
                return false;
            },

            doCssTrans : function(){
                if(plugin.settings.useCSS && this.supportTransition() ){
                    return true;
                }
            },

            gesture : function(){
                if ( isTouch ){
                    var $this = this,
                        distance = null,
                        swipMinDistance = 10,
                        startCoords = {},
                        endCoords = {};
                    var bars = $('#swipebox-caption, #swipebox-action');

                    bars.addClass('visible-bars');
                    $this.setTimeout();

                    $('body').bind('touchstart', function(e){

                        $(this).addClass('touching');

                        endCoords = e.originalEvent.targetTouches[0];
                        startCoords.pageX = e.originalEvent.targetTouches[0].pageX;

                        $('.touching').bind('touchmove',function(e){
                            e.preventDefault();
                            e.stopPropagation();
                            endCoords = e.originalEvent.targetTouches[0];

                        });

                        return false;

                    }).bind('touchend',function(e){
                            e.preventDefault();
                            e.stopPropagation();

                            distance = endCoords.pageX - startCoords.pageX;

                            if( distance >= swipMinDistance ){

                                // swipeLeft
                                $this.getPrev();

                            }else if( distance <= - swipMinDistance ){

                                // swipeRight
                                $this.getNext();

                            }else{
                                // tap
                                if(!bars.hasClass('visible-bars')){
                                    $this.showBars();
                                    $this.setTimeout();
                                }else{
                                    $this.clearTimeout();
                                    $this.hideBars();
                                }

                            }

                            $('.touching').off('touchmove').removeClass('touching');

                        });

                }
            },

            setTimeout: function(){
                if(plugin.settings.hideBarsDelay > 0){
                    var $this = this;
                    $this.clearTimeout();
                    $this.timeout = window.setTimeout( function(){
                            $this.hideBars() },
                        plugin.settings.hideBarsDelay
                    );
                }
            },

            clearTimeout: function(){
                window.clearTimeout(this.timeout);
                this.timeout = null;
            },

            showBars : function(){
                var bars = $('#swipebox-caption, #swipebox-action');
                if(this.doCssTrans()){
                    bars.addClass('visible-bars');
                }else{
                    $('#swipebox-caption').animate({ top : 0 }, 500);
                    $('#swipebox-action').animate({ bottom : 0 }, 500);
                    setTimeout(function(){
                        bars.addClass('visible-bars');
                    }, 1000);
                }
            },

            hideBars : function(){
                var bars = $('#swipebox-caption, #swipebox-action');
                if(this.doCssTrans()){
                    bars.removeClass('visible-bars');
                }else{
                    $('#swipebox-caption').animate({ top : '-50px' }, 500);
                    $('#swipebox-action').animate({ bottom : '-50px' }, 500);
                    setTimeout(function(){
                        bars.removeClass('visible-bars');
                    }, 1000);
                }
            },

            animBars : function(){
                var $this = this;
                var bars = $('#swipebox-caption, #swipebox-action');

                bars.addClass('visible-bars');
                $this.setTimeout();

                $('#swipebox-slider').click(function(e){
                    if(!bars.hasClass('visible-bars')){
                        $this.showBars();
                        $this.setTimeout();
                    }
                });

                $('#swipebox-action').hover(function() {
                    $this.showBars();
                    bars.addClass('force-visible-bars');
                    $this.clearTimeout();

                },function() {
                    bars.removeClass('force-visible-bars');
                    $this.setTimeout();

                });
            },

            keyboard : function(){
                var $this = this;
                $(window).bind('keyup', function(e){
                    e.preventDefault();
                    e.stopPropagation();
                    if (e.keyCode == 37){
                        $this.getPrev();
                    }
                    else if (e.keyCode==39){
                        $this.getNext();
                    }
                    else if (e.keyCode == 27) {
                        $this.closeSlide();
                    }
                });
            },

            actions : function(){
                var $this = this;

                if( elements.length < 2 ){
                    $('#swipebox-prev, #swipebox-next').hide();
                }else{
                    $('#swipebox-prev').bind('click touchend', function(e){
                        e.preventDefault();
                        e.stopPropagation();
                        $this.getPrev();
                        $this.setTimeout();
                    });

                    $('#swipebox-next').bind('click touchend', function(e){
                        e.preventDefault();
                        e.stopPropagation();
                        $this.getNext();
                        $this.setTimeout();
                    });
                }

                $('#swipebox-close').bind('click touchend', function(e){
                    $this.closeSlide();
                });
                $('#swipebox-slider .slide').not($('.mobile #swipebox-slider .slide')).bind('click', function(e){
                    $this.closeSlide();
                });
            },

            setSlide : function (index, isFirst){
                isFirst = isFirst || false;

                var slider = $('#swipebox-slider');

                if(this.doCssTrans()){
                    slider.css({ left : (-index*100)+'%' });
                }else{
                    slider.animate({ left : (-index*100)+'%' });
                }

                $('#swipebox-slider .slide').removeClass('current');
                $('#swipebox-slider .slide').eq(index).addClass('current');
                this.setTitle(index);

                if( isFirst ){
                    slider.fadeIn();
                }

                $('#swipebox-prev, #swipebox-next').removeClass('disabled');
                if(index == 0){
                    $('#swipebox-prev').addClass('disabled');
                }else if( index == elements.length - 1 ){
                    $('#swipebox-next').addClass('disabled');
                }
            },

            openSlide : function (index){
                $('html').addClass('swipebox');
                $(window).trigger('resize'); // fix scroll bar visibility on desktop
                this.setSlide(index, true);
            },

            preloadMedia : function (index){
                var $this = this, src = null;

                if( elements[index] !== undefined )
                    src = elements[index].href;

                if( !$this.isVideo(src) ){
                    setTimeout(function(){
                        $this.openMedia(index);
                    }, 1000);
                }else{
                    $this.openMedia(index);
                }
            },

            openMedia : function (index){
                var $this = this, src = null;

                if( elements[index] !== undefined )
                    src = elements[index].href;

                if(index < 0 || index >= elements.length){
                    return false;
                }

                if( !$this.isVideo(src) ){
                    $this.loadMedia(src, function(){
                        $('#swipebox-slider .slide').eq(index).html(this);
                    });
                }else{
                    $('#swipebox-slider .slide').eq(index).html($this.getVideo(src));
                }

            },

            setTitle : function (index, isFirst){
                var title = null;

                $('#swipebox-caption').empty();

                if( elements[index] !== undefined )
                    title = elements[index].title;

                if(title){
                    $('#swipebox-caption').append(title);
                }
            },

            isVideo : function (src){

                if( src ){
                    if(
                        src.match(/youtube\.com\/watch\?v=([a-zA-Z0-9\-_]+)/)
                            || src.match(/vimeo\.com\/([0-9]*)/)
                        ){
                        return true;
                    }
                }

            },

            getVideo : function(url){
                var iframe = '';
                var output = '';
                var youtubeUrl = url.match(/watch\?v=([a-zA-Z0-9\-_]+)/);
                var vimeoUrl = url.match(/vimeo\.com\/([0-9]*)/);
                if( youtubeUrl ){

                    iframe = '<iframe width="560" height="315" src="//www.youtube.com/embed/'+youtubeUrl[1]+'" frameborder="0" allowfullscreen></iframe>';

                }else if(vimeoUrl){

                    iframe = '<iframe width="560" height="315"  src="http://player.vimeo.com/video/'+vimeoUrl[1]+'?byline=0&amp;portrait=0&amp;color='+plugin.settings.vimeoColor+'" frameborder="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen></iframe>';

                }

                return '<div class="swipebox-video-container" style="max-width:'+plugin.settings.videomaxWidth+'px"><div class="swipebox-video">'+iframe+'</div></div>';
            },

            loadMedia : function (src, callback){
                if( !this.isVideo(src) ){
                    var img = $('<img>').on('load', function(){
                        callback.call(img);
                    });

                    img.attr('src',src);
                }
            },

            getNext : function (){
                var $this = this;
                index = $('#swipebox-slider .slide').index($('#swipebox-slider .slide.current'));
                if(index+1 < elements.length){
                    index++;
                    $this.setSlide(index);
                    $this.preloadMedia(index+1);
                }
                else{

                    $('#swipebox-slider').addClass('rightSpring');
                    setTimeout(function(){
                        $('#swipebox-slider').removeClass('rightSpring');
                    },500);
                }
            },

            getPrev : function (){
                index = $('#swipebox-slider .slide').index($('#swipebox-slider .slide.current'));
                if(index > 0){
                    index--;
                    this.setSlide(index);
                    this.preloadMedia(index-1);
                }
                else{

                    $('#swipebox-slider').addClass('leftSpring');
                    setTimeout(function(){
                        $('#swipebox-slider').removeClass('leftSpring');
                    },500);
                }
            },


            closeSlide : function (){
                $('html').removeClass('swipebox');
                $(window).trigger('resize');
                this.destroy();
            },

            destroy : function(){
                $(window).unbind('keyup');
                $('body').unbind('touchstart');
                $('body').unbind('touchmove');
                $('body').unbind('touchend');
                $('#swipebox-slider').unbind();
                $('#swipebox-overlay').remove();
                if (!$.isArray(elem))
                    elem.removeData('_swipebox');
                if ( this.target )
                    this.target.trigger('swipebox-destroy');
                $.swipebox.isOpen = false;
                if (plugin.settings.afterClose)
                    plugin.settings.afterClose();
            }

        };

        plugin.init();

    };

    $.fn.swipebox = function(options){
        if (!$.data(this, "_swipebox")) {
            var swipebox = new $.swipebox(this, options);
            this.data('_swipebox', swipebox);
        }
        return this.data('_swipebox');
    }

}(window, document, jQuery));